package com.git.smp.utils;

import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

public final class HexBin
{
  private static final int BASELENGTH = 128;
  private static final int LOOKUPLENGTH = 16;
  private static final byte[] hexNumberTable = new byte[''];
  private static final char[] lookUpHexAlphabet = new char[16];

  static
  {
    for (int i = 0; i < 128; i++) {
      hexNumberTable[i] = -1;
    }
    for (int i = 57; i >= 48; i--) {
      hexNumberTable[i] = (byte)(i - 48);
    }
    for (int i = 70; i >= 65; i--) {
      hexNumberTable[i] = (byte)(i - 65 + 10);
    }
    for (int i = 102; i >= 97; i--) {
      hexNumberTable[i] = (byte)(i - 97 + 10);
    }

    for (int i = 0; i < 10; i++) {
      lookUpHexAlphabet[i] = (char)(48 + i);
    }
    for (int i = 10; i <= 15; i++)
      lookUpHexAlphabet[i] = (char)(65 + i - 10);
  }

  public static String encode(byte[] binaryData)
  {
    if (binaryData == null)
      return null;
    int lengthData = binaryData.length;
    int lengthEncode = lengthData * 2;
    char[] encodedData = new char[lengthEncode];

    for (int i = 0; i < lengthData; i++) {
      int temp = binaryData[i];
      if (temp < 0)
        temp += 256;
      encodedData[(i * 2)] = lookUpHexAlphabet[(temp >> 4)];
      encodedData[(i * 2 + 1)] = lookUpHexAlphabet[(temp & 0xF)];
    }
    return new String(encodedData);
  }

  public static byte[] decode(String encoded)
  {
    if (encoded == null)
      return null;
    int lengthData = encoded.length();
    if (lengthData % 2 != 0) {
      return null;
    }
    char[] binaryData = encoded.toCharArray();
    int lengthDecode = lengthData / 2;
    byte[] decodedData = new byte[lengthDecode];

    for (int i = 0; i < lengthDecode; i++) {
      char tempChar = binaryData[(i * 2)];
      byte temp1 = tempChar < '' ? hexNumberTable[tempChar] : -1;
      if (temp1 == -1)
        return null;
      tempChar = binaryData[(i * 2 + 1)];
      byte temp2 = tempChar < '' ? hexNumberTable[tempChar] : -1;
      if (temp2 == -1)
        return null;
      decodedData[i] = (byte)(temp1 << 4 | temp2);
    }
    return decodedData;
  }

  public static void main(String[] args) throws UnsupportedEncodingException {
    String hex = "4CE3998195A28183A38996956E4CC29684A86E4C998598A485A2A36E4C8289A9C29684A8616E4C8289A9C885818485996E4C879396828193E2986EF0F4F9F2F0F1F7F1F1F1F0F0F1F0F2F9F5F7F6F0F2F8F8F0F0F1F0F0F0F0F0F04C61879396828193E2986E4CC5D3C5D4C5D5E3D5E4D46EF84C61C5D3C5D4C5D5E3D5E4D46E4CC9F1E4E2C9C4616E4C978995C9958485A7616E4C81A4A388D7819981616E4C8289A9D985A2E385A7A3616E4C94A287E38994856EF1F47AF3F67AF0F04BF2F8F84C6194A287E38994856E4CC2E4E2C9E3E8D7C56EE2C9D5C7D3C54C61C2E4E2C9E3E8D7C56E4CC2D9D56DC1C3C3616E4CD5D6616E4CC9F1C1E4D7E2616E4C978995E58193A485616E4CE2D7C5C36EF1F24C61E2D7C5C36E4C9697859981A3899695616E4CC3E4E2D5D6616E4CC3D6D5E3C5D5E36EE0C6C9D9E2E30E4C4854CA4E9B4D59585557534D7C50EC5AB00FE0E2C5C3D6D5C4F2F0F1F70E52E90FF1F10E5AC10FF1F00E54D40FE0E3C8C9D9C40E4A6258D25BD10FE0C6C9D9E3C80E4C4854CA4E9B4D59585557534D7C50EC5AB00F4C61C3D6D5E3C5D5E36E4CE2C5D9E5C9C3C5D5D66EF14C61E2C5D9E5C9C3C5D5D66E4C81A4A388C39695A385A7A3616E4CC3E4E2C3C8C5C3D26EF14C61C3E4E2C3C8C5C3D26E4C81A4A388C984616E4CD4E2C76DE3E8D76ED6D74C61D4E2C76DE3E8D76E4C94A287C9846EF0F4F9F2F0F1F7F1F1F1F0F1F4F3F6F0F0F1F5F1F0F2F9F5F7F6F0F2F8F84C6194A287C9846E4CC3C8C1D5D5C5D3D5D6616E4C9985A2E385A7A3616E4CC5D3C5D4C5D5E3E2C9E9C56EF66BF96BF76BF1F16BF66BF36BF66BF94C61C5D3C5D4C5D5E3E2C9E9C56E4C8289A9C9846EC2C9E9C9C44C618289A9C9846E4CC3D6C4C56EF2F2F0F14C61C3D6C4C56E4CA28599A5C3846ED7F0F0F0F0F2F0F0F8F7F6F64C61A28599A5C3846E4CC9D76EF1F04BF04BF1F3F54BF2F44C61C9D76E4CC1C4C4D9C5E2E26EF14C61C1C4C4D9C5E2E26E4CC4C1E36DD5D6616E4CD7D9D6D7C5D9E3E86EF54C61D7D9D6D7C5D9E3E86E4C94A287C481A3856EF2F0F1F760F1F160F1F04C6194A287C481A3856E4CA28599A58599C384616E4CC3C8C5C3D26EF14C61C3C8C5C3D26E4CA3998195C3968485616E4CC9D5D5C5D96DC1C3C3616E4CA3859994C3846EF1F04BF1F44BF1F5F44BF1F4F77EF1F04BF1F44BF1F5F44BF2F5F44C61A3859994C3846E4CA2A8A2C3846EF0F4F94C61A2A8A2C3846E4C8289A9E3A897856E8289A9E3A897854C618289A9E3A897856E4C9985A2C384616E4C8289A9D985A2C384616E4CC9F1C1E4E4E2616E4C969987C3846EF3F4F0F0F0F0F8F8F8F84C61969987C3846E4CC9F1E2C2D5D6616E4C618289A9C885818485996E4C61998598A485A2A36E4C61C29684A86E4CC885818485996E4CA2A8A2C885818485996E4C879396828193E2986EF0F4F9F2F0F1F7F1F1F1F0F0F1F0F2F9F5F7F6F0F2F8F8F0F0F1F0F0F0F0F0F04C61879396828193E2986E4CA28599A5C3846ED9F0F4F0F0F2F0F0F8F0F1F34C61A28599A5C3846E4C978995C9958485A7616E4C8289A9D985A2E385A7A3616E4C81A4A388D7819981616E4C94A287C481A3856EF2F0F1F760F1F160F1F04C6194A287C481A3856E4C94A287E38994856EF1F47AF3F67AF0F04BF2F8F84C6194A287E38994856E4CA28599A58599C384616E4C978995E58193A485616E4C9697859981A3899695616E4C81A4A388C39695A385A7A3616E4CA3998195C39684856EE9C8E3C94C61A3998195C39684856E4C81A4A388C984616E4CA3859994C3846EF1F04BF1F44BF1F5F44BF1F4F77EF1F04BF1F44BF1F5F44BF2F5F44C61A3859994C3846E4C94A287C9846EF0F4F9F2F0F1F7F1F1F1F0F1F4F3F6F0F0F1F5F1F0F2F9F5F7F6F0F2F8F84C6194A287C9846E4CA2A8A2C3846EF0F4F94C61A2A8A2C3846E4C8289A9D985A2C384616E4C9985A2E385A7A3616E4C9985A2C384616E4C8289A9E3A897856E8289A9E3A897854C618289A9E3A897856E4C8289A9C9846EC2C9E9C9C44C618289A9C9846E4C969987C3846EF3F4F0F0F0F0F8F8F8F84C61969987C3846E4C61A2A8A2C885818485996E4C61C885818485996E4C61E3998195A28183A38996956E";
    byte[] decode = decode(hex);
    System.out.println(new String(decode, "UTF-8"));
  }
}